/*
 * Copyright [2009] [Marcin Rzeźnicki]

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
 */
package mr.go.yaxc;

import java.util.List;

import org.slf4j.Logger;
import org.xml.sax.ContentHandler;

/**
 * Provides {@link Action} with ability to check context of its execution and
 * maintains global repository of object references. Action's scope can be
 * thought of as parameters, properties and/or target object which have been set
 * by calling action's logical parent, that is: an action executed before this
 * action and not yet processed. In terms of XML parsing, parent action is an
 * action attached to XML element for which
 * {@link ContentHandler#startElement(String, String, String, org.xml.sax.Attributes)
 * startElement} was called, but not
 * {@link ContentHandler#endElement(String, String, String) endElement}. Local
 * scope has stack-like lifetime - after successful processing of a node, local
 * scope is gone. For objects which can be referenced throughout whole parsing,
 * global scope is maintained.
 * 
 * @author Marcin Rzeźnicki
 * 
 */
public interface ScopeHandler {

    /**
     * Called when {@code Action} has to pass parameter to its logical parent.
     * When no parameters can be found in calling action's scope warning is
     * emitted.
     *
     * @param o
     *            param to be set
     */
    public void addParam(Object o);

    /**
     * Logger through which calling action may output messages to user
     *
     * @return logger
     */
    public Logger getLogger();

    /**
     * XML namespace URI for yaxc nodes
     *
     * @return uri or empty string
     */
    public String getNamespace();

    /**
     * Called when {@code Action} needs to obtain property from its logical
     * parent
     *
     * @param property
     *            property name
     * @return property value or null
     */
    public Object getParentProperty(String property);

    /**
     * Called when {@code Action} needs to find object in global context
     *
     * @param id
     *            reference id
     * @return global object or null if not found
     */
    public Object getReference(String id);

    /**
     * Called when {@code Action} has to obtain parameters of its parent. When
     * no params can be found in calling action's scope warning is emitted
     *
     * @return list of parameters set by parent
     */
    public List<Object> params();

    /**
     * Called when {@code Action} needs to reference object from parent scope.
     * If no such object exists warning is emitted
     *
     * @return object set by parent or null if not found
     */
    public Object parentObject();

    /**
     * Called when {@code Action} needs to set property for its logical parent
     * to inspect. It is illegal to call this method when no properties are set
     * by parent
     *
     * @param property
     *            property key
     * @param value
     *            property value
     */
    public void setParentProperty(String property, Object value);

    /**
     * Sets object in global context.
     *
     * @param id
     *            reference id
     * @param o
     *            object
     */
    public void setReference(String id, Object o);

    /**
     * Called when {@code Action} has to pass parameter to its parent. When no
     * parameters can be found in calling action's scope this call is silently
     * ignored
     *
     * @param o
     *            param to be set
     */
    public void tryAddParam(Object o);
}
